﻿using System;
using HK.Core.Common.Data;
using HK.Core.Common.Protocol.Data;
using HK.Core.GUIEx.Protocol.Attribute;
using HK.Core.Utils;
using HK.Editor.GUIEx.Protocol.Data;
using UnityEngine;

namespace HK.Editor.GUIEx.Data
{
    /// <summary>
    /// 窗体配置信息
    /// </summary>
    [Serializable]
    public sealed class WindowConf : JsonData<WindowConf>, IWindowConf
    {

#region Create

        /// <summary>
        /// 创建窗体配置信息
        /// </summary>
        /// <param name="iName">窗体名</param>
        /// <param name="iRect">显示区域</param>
        /// <param name="iOptions">选项</param>
        /// <param name="iTitle">标题</param>
        /// <returns>窗体配置信息</returns>
        public static WindowConf Create(string iName, Rect iRect, int iOptions = (int)GUIOperateOptions.None, string iTitle = null)
        {
            return new WindowConf
            {
                winName = iName, displayRect = iRect, 
                Options = iOptions, title = iTitle
            };
        }

#endregion

        /// <summary>
        /// 保护构造函数
        /// </summary>
        private WindowConf()
        {
            createTime = UtilsTime.GetCurDateTimeTicks();
        }
        
        [SerializeField]
        private string winName = null;
        /// <summary>
        /// 窗体名
        /// </summary>
        public string WinName
        {
            get => winName;
            private set => winName = value;
        }
        
        [SerializeField]
        private string title = null;
        /// <summary>
        /// 标题
        /// </summary>
        public string Title 
        {
            get => title;
            private set => title = value;
        }

        [SerializeField]
        private Rect displayRect;
        /// <summary>
        /// 显示区域
        /// </summary>
        public Rect DisplayRect 
        {
            get => displayRect;
            private set => displayRect = value;
        }

        /// <summary>
        /// 位置
        /// </summary>
        public Vector2 Pos => displayRect.position;
        
        /// <summary>
        /// 宽度
        /// </summary>
        public float Width => displayRect.width;
        
        /// <summary>
        /// 高度
        /// </summary>
        public float Height => displayRect.height;
        
#region Options

        [SerializeField]
        private int options = (int)GUIOperateOptions.None;

        /// <summary>
        /// 选项
        /// </summary>
        public int Options
        {
            get => options;
            private set => options = value;
        }

        /// <summary>
        /// 展开缩进
        /// </summary>
        public bool Expandable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Expandable);
        
        /// <summary>
        /// 可拖拽
        /// </summary>
        public bool Draggable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Draggable);

        /// <summary>
        /// 可排序
        /// </summary>
        public bool Sortable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Sortable);

        /// <summary>
        /// 可追加
        /// </summary>
        public bool Addable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Addable);
        
        /// <summary>
        /// 可移除
        /// </summary>
        public bool Removable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Removable);

        /// <summary>
        /// 可分页
        /// </summary>
        public bool Pageable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Pageable);

        /// <summary>
        /// 可编辑
        /// </summary>
        public bool Editable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Editable);

        /// <summary>
        /// 可检索
        /// </summary>
        public bool Searchable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Searchable);

        /// <summary>
        /// 可导入
        /// </summary>
        public bool Importable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Importable);

        /// <summary>
        /// 可导出
        /// </summary>
        public bool Exportable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Exportable);

        /// <summary>
        /// 可清楚
        /// </summary>
        public bool Clearable => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Clearable);
        
        /// <summary>
        /// 可帮助的
        /// <para>* 窗体右上角，工具栏处有帮助按钮</para>
        /// </summary>
        public bool Helpful => UtilsBytes.CheckBytes(options, (int)GUIOperateOptions.Helpful);

#endregion
        
        [SerializeField]
        private long createTime = 0L;

        private string _createTimeTxt = null;
        /// <summary>
        /// 创建世间
        /// </summary>
        public string CreateTime
        {
            get
            {
                if (!string.IsNullOrEmpty(_createTimeTxt)) return _createTimeTxt;
                _createTimeTxt = UtilsTime.ConvertByFormat(createTime);
                return _createTimeTxt;
            }
        }

        /// <summary>
        /// 刷新
        /// </summary>
        public void Refresh()
        {
            createTime = UtilsTime.GetCurDateTimeTicks();
            _createTimeTxt = null;
        }

        /// <summary>
        /// 应用数据
        /// </summary>
        /// <param name="iData">数据</param>
        /// <param name="iImport">导入标志位(true:从相应的*.json文件导入; false:反之;)</param>
        /// <returns>true:有变更; false:无变更;</returns>
        public override bool ApplyData(IJsonData iData, bool iImport = false)
        {
            if (null == iData || !iData.Valid) return false;

            var dirty = base.ApplyData(iData, iImport);
            if (dirty && !iImport)
            {
                Dirty = true;
            }

            if (iData is IWindowConf conf)
            {
                winName = UpdateValue(winName, conf.WinName, iImport);
                title = UpdateValue(title, conf.Title, iImport);
                displayRect = UpdateValue(displayRect, DisplayRect, iImport);
            }
            
            // 刷新
            if (Dirty)
            {
                Refresh();
            }

            return Dirty;
        }
        
        /// <summary>
        /// 更新值
        /// </summary>
        /// <param name="iCurValue">当前值</param>
        /// <param name="iDstValue">目标值</param>
        /// <param name="iImport">导入标志位</param>
        /// <returns>可以更新的值</returns>
        private Rect UpdateValue(Rect iCurValue, Rect iDstValue, bool iImport)
        {
            
            var dirty = iCurValue != iDstValue;
            if (dirty && !iImport)
            {
                Dirty = true;
            }

            return dirty ? iDstValue : iCurValue;
        }

        /// <summary>
        /// 清空
        /// </summary>
        public override void Clear()
        {
            base.Clear();
            
            winName = null;
            title = null;
            displayRect = Rect.zero;
            createTime = 0L;
        }
    }
}
